package com.acwer.drgs.performance.controller;

import com.acwer.common.RpnMsg;
import com.acwer.dao.domain.DrgStd;
import com.acwer.dao.domain.DrgStd3;
import com.acwer.dao.mapper.DrgStdMapper;
import com.acwer.dao.mapper.DrgStdMapper3;
import com.acwer.dao.mapper.MiniPfmMapper;
import com.acwer.drgs.performance.config.ApplicationValues;
import com.acwer.drgs.performance.config.HttpUtils;
import com.acwer.drgs.performance.domain.RqGrp;
import com.acwer.drgs.performance.es.domain.MiniPerformanceInfo;
import com.acwer.drgs.performance.es.domain.PerfmDic;
import com.acwer.drgs.performance.es.repo.MiniPerformanceRepo;
import com.acwer.drgs.performance.es.repo.PerfmDicRepo;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.beanutils.BeanUtils;
import org.elasticsearch.action.DocWriteRequest;
import org.elasticsearch.action.bulk.BulkItemResponse;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.util.Streamable;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.annotation.RequestScope;

import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;


/**
 * 以下为一个简单的测试程序
 */
//@Slf4j(topic = "ApiController")
@RestController
@RequestMapping("api")
//用于nacos刷新配置
@RequestScope

@Api(value = "测试服务",tags = "ApiController测试相关接口",description = "用于测试当前服务相关配置是否正常<br/>其他相关接品请另起controller")
public class ApiController {

//获取NACOS配置的信息
    @Value("${info:false}")
    private String info;

    //SW参数说明
    @ApiImplicitParams({
            @ApiImplicitParam(name = "str",value = "没有任何意义，用于测试SW")
    })
    //该方法的说明
    @ApiOperation(value = "获取nacos上info配置的信息",notes = "测试nacos配置是否正常")
    @GetMapping("info")
    @SentinelResource("info")
    public RpnMsg info(@RequestParam(defaultValue = "") String str){
        return RpnMsg.SUCCESS(info);
    }


    @Autowired
    MiniPfmMapper miniPfmMapper;

    @Autowired
    MiniPerformanceRepo repo2;

    @Autowired
    RestHighLevelClient client;


    @Autowired
    ElasticsearchRestTemplate restTemplate;

    @Autowired
    ApplicationValues applicationValues;

    HttpUtils httpUtils = new HttpUtils();

    private MiniPerformanceInfo.GrpInfo grp(MiniPerformanceInfo info){

        RqGrp rqGrp=new RqGrp();
        //主要诊断
        rqGrp.setMDCode(info.getJbdm());
        //其他诊断编码
        rqGrp.setODCodes(new ArrayList<String>(){
                             {   if(info.getJbdm1()!=null){
                                 add(info.getJbdm1());
                             }
                                 if(info.getJbdm2()!=null){
                                     add(info.getJbdm2());
                                 }
                                 if(info.getJbdm3()!=null){
                                     add(info.getJbdm3());
                                 }
                                 if(info.getJbdm4()!=null){
                                     add(info.getJbdm4());
                                 }
                                 if(info.getJbdm5()!=null){
                                     add(info.getJbdm5());
                                 }
                                 if(info.getJbdm6()!=null){
                                     add(info.getJbdm6());
                                 }
                                 if(info.getJbdm7()!=null){
                                     add(info.getJbdm7());
                                 }
                                 if(info.getJbdm8()!=null){
                                     add(info.getJbdm8());
                                 }
                                 if(info.getJbdm9()!=null){
                                     add(info.getJbdm9());
                                 }
                                 if(info.getJbdm10()!=null){
                                     add(info.getJbdm10());
                                 }
                                 if(info.getJbdm11()!=null){

                                     add(info.getJbdm11());
                                 }
                                 if(info.getJbdm12()!=null){
                                     add(info.getJbdm12());
                                 }
                                 if(info.getJbdm13()!=null){
                                     add(info.getJbdm13());
                                 }
                                 if(info.getJbdm14()!=null){
                                     add(info.getJbdm14());
                                 }
                                 if(info.getJbdm15()!=null){
                                     add(info.getJbdm15());
                                 }
                             }
                         }
        );
        //主手术编码
        rqGrp.setMOpCode(info.getSsjczbm1());
        rqGrp.setOpCodes(new ArrayList<String>(){
            {
                if (info.getSsjczbm1()!=null) {

                    add(info.getSsjczbm1());

                }
                if (info.getSsjczbm2()!=null) {

                    add(info.getSsjczbm2());
                }

                if (info.getSsjczbm3()!=null) {

                    add(info.getSsjczbm3());
                }

                if (info.getSsjczbm4()!=null) {

                    add(info.getSsjczbm4());
                }

                if (info.getSsjczbm5()!=null) {

                    add(info.getSsjczbm5());
                }

                if (info.getSsjczbm6()!=null) {

                    add(info.getSsjczbm6());
                }

                if (info.getSsjczbm7()!=null) {

                    add(info.getSsjczbm7());
                }

            }
        });
        rqGrp.setAge(info.getNl());
        rqGrp.setGender(Integer.parseInt(info.getXb()));
        rqGrp.setAmount(info.getZfy());

        rqGrp.setBah(info.getBah());
        rqGrp.setNeoWeight(info.getXsecstz().toString());
        rqGrp.setNeoHosptWeight(info.getXserytz().toString());
        rqGrp.setLenOfStasy(Double.parseDouble(info.getSjzyts()));
        rqGrp.setLeaveWay(Integer.parseInt(info.getLyfs()));
        rqGrp.setIcd9Edition("1");
        rqGrp.setIcd10Edition("1");
        rqGrp.setDrgEdtion("CHSDRG");
        rqGrp.setUserName(info.getUsername());
        rqGrp.setBah(info.getBah());
        rqGrp.setGender(Integer.parseInt(info.getXb()));
        rqGrp.setUserName(info.getUsername());
        rqGrp.setMDCode(info.getJbdm());
        String jsonStr=JSON.toJSONString(rqGrp);
        System.out.println("jsonstr:"+jsonStr);
        RpnMsg rpnMsg1 =httpUtils.sendPost(jsonStr, applicationValues.getUri());

        try {
            MiniPerformanceInfo.GrpInfo info1=new MiniPerformanceInfo.GrpInfo();
            BeanUtils.populate(info1, (Map<String, ? extends Object>) rpnMsg1.getData());
            return info1;
        }catch (Exception ex){
            return null;
        }
        //return null;
    }


    @Autowired
    DrgStdMapper drgStdMapper;

    @Autowired
    DrgStdMapper3 drgStdMapper3;
    @GetMapping("dao")
    public RpnMsg dao(){
        RpnMsg msg=RpnMsg.SUCCESS();
//        IPage<Map<String,Object>> page=new Page<>(1,10);
//        int page=306;
        int size=100;
        int total=12864;
        QueryWrapper<DrgStd> query=new QueryWrapper<>();
        query.eq("版本","CHSDRG");

        QueryWrapper<DrgStd3> query3=new QueryWrapper<>();
        query3.eq("版本","CHSDRG");

        List<DrgStd> drgStds = drgStdMapper.selectList(query);
        List<DrgStd3> drgStd3s=drgStdMapper3.selectList(query3);

        int pages=(total+(size-1))/size;
        for (int i = 97; i <=pages; i++) {
            int m=(i-1)*size+1;
            List<Map<String, Object>> ls = miniPfmMapper.selectAll(m,size*i);

            BulkRequest bulkRequest=new BulkRequest();

            Map<String, String> inGrpMap = new HashMap<String, String>(){
                {
                    // 外科
                    put("wk", ".[a-j].*");
                    // 操作
                    put("cz", ".[k-q].*");
                    // 内科
                    put("nk", ".[r-z].*");
                }
            };
            Map<Integer,String> usernameMap=new HashMap<Integer,String>(){
                {
                    put(0,"江津中心医院");
                    put(1,"江津中心医院2");
                }
            };
            for (Map<String, Object> mm : ls) {
                Map<String,Object>nm=keyToLowerCase(mm);
                nm.put("@timestamp",new Date());

                MiniPerformanceInfo info=new MiniPerformanceInfo();
                try {
                    BeanUtils.populate(info, nm);

                }catch (Exception ex){}

                try {
                    MiniPerformanceInfo.GrpInfo grp = grp(info);
                    for (int j = 0; j <2; j++) {
                        boolean f=!StringUtils.isEmpty(grp.getMdc())&&grp.getMdc().startsWith("MDC");
                        nm.put("ingrp",f);
                        nm.put("username",usernameMap.get(j));
                        String code = grp.getDrg();
                        double benchmarkFee=0;
                        double benchmarkStayDays=0;
                        double weight=0;
                        if(!StringUtils.isEmpty(code)){
                            List<DrgStd> tmpDrgStd1 = drgStds.stream().filter(it -> it.get分组编码().equals(code)).collect(Collectors.toList());
                            List<DrgStd3> tmpDrgStd2 = drgStd3s.stream().filter(it -> it.get分组编码().equals(code)).collect(Collectors.toList());

                            benchmarkFee=j==0?tmpDrgStd1.get(0).get平均费用():tmpDrgStd2.get(0).get平均费用();
                            benchmarkStayDays=j==0?tmpDrgStd1.get(0).get平均床日():tmpDrgStd2.get(0).get平均床日();
                            weight=j==0?tmpDrgStd1.get(0).get权重():tmpDrgStd2.get(0).get权重();
                            grp.setBenchmarkFee(benchmarkFee);
                            grp.setBenchmarkStayDays(benchmarkStayDays);
                            grp.setWeight(weight);
                            JSONObject o = (JSONObject)JSON.toJSON(grp);
                            if(f){
                                o.put("costratio",info.getZfy()/benchmarkFee);
                                o.put("bedratio",Double.parseDouble(info.getSjzyts())/benchmarkStayDays);
                                for (Map.Entry<String, String> entry : inGrpMap.entrySet()) {
                                    if(Pattern.matches("(?i)"+entry.getValue(), grp.getDrg())){
                                        o.put("drgingrptype",entry.getKey());
                                        break;
                                    }
                                }
                                nm.put("grpinfo",o);
                            }

                        }else{
                            JSONObject o = (JSONObject)JSON.toJSON(grp);
                            nm.put("grpinfo",o);
                        }

                        IndexRequest request=new IndexRequest("minipfm-stream")
                                .source(nm)
                                .opType(DocWriteRequest.OpType.CREATE);
                        bulkRequest.add(request);
                    }

                }catch (Exception ee){
                    ee.printStackTrace();
                    for (Map.Entry<Integer, String> entry : usernameMap.entrySet()) {
                        nm.put("ingrp",false);
                        nm.put("username",entry.getValue());

                        IndexRequest request=new IndexRequest("minipfm-stream")
                                .source(nm)
                                .opType(DocWriteRequest.OpType.CREATE);
                        bulkRequest.add(request);
                    }
                }


            }

          try {

              BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
              System.out.println("当前页："+i+",总页数："+pages);
              bulkRequest=new BulkRequest();
          }catch (Exception e){
              e.printStackTrace();
          }


        }

        return msg;
    }
    public static Map<String, Object> keyToLowerCase(Map<String, Object> orgMap) {
        Map<String, Object> resultMap = new HashMap<>();

        if (orgMap == null || orgMap.isEmpty()) {
            return resultMap;
        }
        Set<Map.Entry<String, Object>> entrySet = orgMap.entrySet();
        for (Map.Entry<String, Object> entry : entrySet) {
            String key = entry.getKey();
            Object value = entry.getValue();
            resultMap.put(key.toLowerCase(), value);
        }
        return resultMap;
    }
    @Autowired
    PerfmDicRepo repo;
    @ApiOperation(value = "获取ES上Test索引数据",notes = "测试其连通性、安全验证")
    @GetMapping("es")
    public RpnMsg<PerfmDic> es(){



//        Map<Tuple<String,String>,List<Tuple<String,String>>> map=new HashMap<Tuple<String,String>,List<Tuple<String,String>>>(){
//            {
//                put(new Tuple<String,String>("ylfkfs","医疗付款方式代码"),new ArrayList<Tuple<String,String>>(){
//                    {
//                        add(new Tuple<String,String>("01","城镇职工基本医疗保险"));
//                        add(new Tuple<String,String>("02","城镇居民基本医疗保险"));
//                        add(new Tuple<String,String>("03","新型农村合作医疗"));
//                        add(new Tuple<String,String>("04","贫困救助"));
//                        add(new Tuple<String,String>("05","商业医疗保险"));
//                        add(new Tuple<String,String>("06","全公费"));
//                        add(new Tuple<String,String>("07","全自费"));
//                        add(new Tuple<String,String>("08","其他社会保险"));
//                        add(new Tuple<String,String>("99","其他"));
//                    }
//                });
//
//                put(new Tuple<String,String>("xb","性别代码"),new ArrayList<Tuple<String,String>>(){
//                    {
//                        add(new Tuple<String,String>("0","未知的性别"));
//                        add(new Tuple<String,String>("1","男"));
//                        add(new Tuple<String,String>("2","女"));
//                        add(new Tuple<String,String>("9","未说明的性别"));
//                    }
//                });
//
////                职业代码
////                11	国家公务员
////                13	专业技术人员
////                17	职员
////                21	企业管理人员
////                24	工人
////                27	农民
////                31	学生
////                37	现役军人
////                51	自由职业者
////                54	个体经营者
////                70	无业人员
////                80	退(离)休人员
////                90	其他
//                put(new Tuple<String,String>("zy","职业代码"),new ArrayList<Tuple<String,String>>(){
//                    {
//                        add(new Tuple<String,String>("11","国家公务员"));
//                        add(new Tuple<String,String>("13","专业技术人员"));
//                        add(new Tuple<String,String>("17","职员"));
//                        add(new Tuple<String,String>("21","企业管理人员"));
//                        add(new Tuple<String,String>("24","工人"));
//                        add(new Tuple<String,String>("27","农民"));
//                        add(new Tuple<String,String>("31","学生"));
//                        add(new Tuple<String,String>("37","现役军人"));
//                        add(new Tuple<String,String>("51","自由职业者"));
//                        add(new Tuple<String,String>("54","个体经营者"));
//                        add(new Tuple<String,String>("70","无业人员"));
//                        add(new Tuple<String,String>("80","退(离)休人员"));
//                        add(new Tuple<String,String>("90","其他"));
//                    }
//                });
//            }
//        };
//
//        List<PerfmDic> ls=new ArrayList<>();
//        for (Map.Entry<Tuple<String, String>, List<Tuple<String, String>>> entry : map.entrySet()) {
//            String id=UUID.randomUUID().toString();
//            ls.add(new PerfmDic(){
//                {
//                    setId(id);
//                    setJoin(new JoinField<>("p"));
//                    setCode(entry.getKey().v1());
//                    setName(entry.getKey().v2());
//                }
//            });
//
//            for (Tuple<String, String> tuple : entry.getValue()) {
//                ls.add(new PerfmDic(){
//                    {
//                        setId(UUID.randomUUID().toString());
//                        setJoin(new JoinField<>("c",id));
//                        setCode(tuple.v1());
//                        setName(tuple.v2());
//                    }
//                });
//            }
//        }
//
//        repo.saveAll(ls);



        RpnMsg msg=new RpnMsg<PerfmDic>();
        return msg;
    }
}
